#pragma once
#include <sys/epoll.h>
#include <ext/hash_map>
#include <ext/hash_set>
#include "event_base.h"
#include "Epoll.h"
#include <sys/socket.h>
#include <arpa/inet.h>
/*
 *
 * event_loop事件处理机制
 *
 */

#define MAXEVENTS 10

// map: fd->io_event
typedef __gnu_cxx::hash_map<int, io_event> io_event_map;
// 定义指向上面map类型的迭代器
typedef __gnu_cxx::hash_map<int, io_event>::iterator io_event_map_it;
// 全部正在监听的套接字fd集合
typedef __gnu_cxx::hash_set<int> listen_fd_set;

/*
    event_loop()：构造函数，主要初始化epoll.
    event_process():永久阻塞，等待触发的事件，去调用对应的函数callback方法。
    add_io_event():绑定一个fd和一个io_event的关系，并添加对应的事件到event_loop中。
    del_io_event():从event_loop删除该事件。
*/
class event_loop
{
public:
    event_loop();
    // 阻塞循环处理事件
    void event_process();

    // 添加一个io事件到loop中
    void add_io_event(int fd, io_callback *proc, int mask, void *args);

    // 删除一个io事件从loop中
    void del_io_event(int fd);

    // 删除一个io事件的EPOLLIN/EPOLLOUT
    void del_io_event(int fd, int mask);

private:
    void Dispatcher();
    void HandlerEvent(int n);
    void Accepter();

private:
    int _epfd;
    io_event_map _evs; // map: fd->io_event
    listen_fd_set _listenfds;
    // 一次性最大处理的事件
    struct epoll_event _fired_evs[MAXEVENTS];
};